package owg.util.opengl;

import owg.util.euclidian.Compass;
import owg.util.euclidian.MatrixStack;
import owg.util.opengl.models.HPRF;


public class SpriteFontRenderer implements GLFont
{
	private Tex fontTexture;
	private ColorProducer colorP;
	private HPRF box;
	private String fontName;
	private float lineSeparation;
	private float charSeparation;
	
	public SpriteFontRenderer(String fontName, ColorF color, float charSeparation, float lineSeparation)
	{
		this.fontName = fontName;
		this.colorP = new PlainColor(color);
		this.charSeparation = charSeparation;
		this.lineSeparation = lineSeparation;
	}
	public void render(EGL<?> egl, String string, int x, int y, Compass orientation)
	{ 
		render(egl, string, x, y, orientation, 1f, 1f, 0);
	}
	public void render(EGL<?> egl, String string, float x, float y, Compass orientation, float xScale, float yScale, float angle)
	{
		render(egl, string.split("\n", -1), x, y, orientation, xScale, yScale, angle);
	}
	public void render(EGL<?> egl, String[] strings, int x, int y, Compass orientation)
	{
		render(egl, strings, x, y, orientation, 1, 1, 0);
	}
	public void render(EGL<?> egl, String[] strings, float x, float y, Compass orientation, float xScale, float yScale, float angle)
	{
		EGL<?> glUtil = egl;
		Tex font = tex();
		if(box == null)
			box = PrimitiveFactory.genSquare(egl, 0, 0, font.getWidth(), font.getHeight(), 1, 1);
		MatrixStack m = glUtil.modelviewMatrix();
		m.push();
		
		m.scalef(xScale, yScale, 1);
		m.rotatef(angle, 0, 0, -1);
		m.translatef(x, y, 0);
		
		float yOff = -(getStringHeight(strings.length)-(lineSeparation-1)*font.getHeight())*orientation.dy;
		m.translatef(0, yOff, 0);
		for(int py = 0; py<strings.length; py++)
		{
			m.push();
			m.translatef(-(getStringWidth(strings[py])-(charSeparation-1)*font.getWidth())*orientation.dx, 0, 0);
			for(int px = 0; px<strings[py].length(); px++) 
			{
				ColorF color = colorP.getColor(strings[py], py, px); 
				if(color != null)
					egl.setColor(color);
				
				char c = strings[py].charAt(px);
				egl.enableTexture2D(font, c);
				box.render();
				m.translatef(getCharWidth(), 0, 0);
			}
			m.pop();
			m.translatef(0, getLineHeight(), 0);
		}
		egl.disableTexture2D();
		m.pop();
	}
	
	public void renderConstrained(EGL<?> egl, String text, int x, int y, Compass orientation, int maxWidth)
	{
		String[] lines = text.split("\n", -1);
		if(getStringWidth(lines) > maxWidth)
		{
			int maxChars = (int)((maxWidth)/getCharWidth()-(1-charSeparation));
			for(int i = 0; i<lines.length; i++)
			{
				if(maxChars >= 3)
					lines[i] = lines[i].substring(0, maxChars-3)+"...";
				else
					lines[i] = "";
			}				
			render(egl, lines, x, y, orientation, 1, 1, 0);
		}
		else
			render(egl, text, x, y, orientation, 1, 1, 0);
	}
	private Tex tex()
	{
		if(fontTexture == null)
			fontTexture = TextureLib.tex(fontName);
		return fontTexture;
	}
	public float getStringHeight(String string)
	{
		if(string == null)
			return 0;
		return getStringHeight(string.split("\n", -1).length);
	}
	
	public float getStringHeight(int lines)
	{
		return lines*getLineHeight();
	}
	
	public float getLineHeight()
	{
		return (tex().getHeight()*lineSeparation);
	}
	
	public float getStringWidth(String string)
	{
		if(string == null)
			return 0;
		return getStringWidth(string.split("\n", -1));
	}
	
	public float getStringWidth(String[] strings)
	{	
		float maxWidth = 0;
		for(int i = 0; i<strings.length; i++)
		{
			if(strings[i].length() > 0)
				maxWidth = Math.max(maxWidth, tex().getWidth() + getCharWidth() * (strings[i].length()-1));
		}
		return maxWidth;
	}
	public float getCharWidth(char c)
	{
		return getCharWidth();
	}
	
	public float getCharWidth()
	{
		return tex().getWidth()*charSeparation;
	}
	@Override
	public void setColorProducer(ColorProducer color)
	{
		this.colorP = color;
	}
	@Override
	public int getSize()
	{
		return tex().getHeight();
	}
}
